package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.excetion.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.web.admin.mapper.*;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentDetailVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentItemVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentQueryVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentSubmitVo;
import com.atguigu.lease.web.admin.vo.fee.FeeValueVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/*  这里来到了 ApartmentInfoService 的实现类重写自定义的方法
 * 翻译成人话：
 * ApartmentInfoServiceImpl 这个类：
 *
 * 1. 继承 ServiceImpl(类)  (SpringBoot自带的父类)
 *    IService是接口,接口不能继承,只有类才能继承
 *    → 获得SpringBoot自带的 增删改查 方法
 *    → 使用 ApartmentInfoMapper 操作数据库
 *    → 操作 ApartmentInfo 实体（对应 apartment_info 表）
 */
@Service
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
        implements ApartmentInfoService {
    //先注入三张中间表
    @Autowired
    private ApartmentFacilityService apartmentFacilityService;
    @Autowired
    private ApartmentFeeValueService apartmentFeeValueService;
    @Autowired
    private ApartmentLabelService apartmentLabelService;
    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    @Lazy
    private RoomInfoService roomInfoService;

    //导入公寓关联的Mapper
    @Autowired
    private ApartmentInfoMapper apartmentInfoMapper;
    @Autowired
    private FacilityInfoMapper facilityInfoMapper;
    @Autowired
    private LabelInfoMapper labelInfoMapper;
    @Autowired
    private GraphInfoMapper graphInfoMapper;
    @Autowired
    private FeeValueMapper feeValueMapper;


    @Override
    public void saveOrUpdateApartment(ApartmentSubmitVo amvo) {
        //先获取主键ID判断是否为空 ,不为空就是更新
        boolean isUpdate = amvo.getId() != null;
        boolean result = super.saveOrUpdate(amvo);
        System.out.println("公寓信息注入成功");
        Long apartmentId = amvo.getId();
        if (isUpdate) {  //更新,删除中间表
            //获取公寓ID

            //删除配套中间表,根据公寓ID删除
            LambdaQueryWrapper<ApartmentFacility> wrapperFacility = new LambdaQueryWrapper<>();
            wrapperFacility.eq(ApartmentFacility::getApartmentId, apartmentId);  // wrapper.eq(字段引用, 具体的条件值);
            apartmentFacilityService.remove(wrapperFacility);
            System.out.println("配套信息删除成功");

            //删除杂费中间表
            LambdaQueryWrapper<ApartmentFeeValue> wrapperFee = new LambdaQueryWrapper<>();
            wrapperFee.eq(ApartmentFeeValue::getApartmentId, apartmentId);
            apartmentFeeValueService.remove(wrapperFee);
            System.out.println("杂费信息删除成功");

            //删除标签中间表
            LambdaQueryWrapper<ApartmentLabel> wrapperLabel = new LambdaQueryWrapper<>();
            wrapperLabel.eq(ApartmentLabel::getApartmentId, apartmentId);
            apartmentLabelService.remove(wrapperLabel);
            System.out.println("标签信息删除成功");

            //删除图片
            LambdaQueryWrapper<GraphVo> graphWrapper = new LambdaQueryWrapper<>();
            graphWrapper.eq(GraphVo::getItemId, apartmentId);
            graphWrapper.eq(GraphVo::getItemType, ItemType.APARTMENT);
            graphInfoService.remove(graphWrapper);

        }
        //=============保存_配套数据================
        List<Long> facilityId = amvo.getFacilityInfoIds(); //获取配套id
        //不为空 → 说明用户前端选了标签 需要插入数据
        if (!CollectionUtils.isEmpty(facilityId)) {
            //这里循环的是配套id_目的是让配套id和公寓id对应起来
            ArrayList<ApartmentFacility> arrFacility = new ArrayList<>();
            for (Long s : facilityId) {
                ApartmentFacility apartMentFacility = ApartmentFacility.builder()
                        .apartmentId(apartmentId)
                        .facilityId(s)
                        .build();
                //循环一个添加一个配套id匹配
                arrFacility.add(apartMentFacility);
            }
            //保存到设备中间表
            apartmentFacilityService.saveBatch(arrFacility);
            System.out.println("配套信息插入成功");
        }

        //=============保存_标签数据================
        List<Long> labelId = amvo.getLabelIds();
        if (labelId != null && !labelId.isEmpty()) {
            //不为空 → 说明用户选了标签 需要插入数据
            ArrayList<ApartmentLabel> arrLabel = new ArrayList<>();
            for (Long s : labelId) {
                //循环的每一条 labelId 赋值给s,此时s就是标签id
                ApartmentLabel apartmentLabel = ApartmentLabel.builder()
                        .apartmentId(apartmentId)
                        .labelId(s)
                        .build();
                //每次添加完两个标签id就需要添加到数组里
                arrLabel.add(apartmentLabel);
            }
            apartmentLabelService.saveBatch(arrLabel);
            System.out.println("标签信息插入成功");
        }

        // ========== 插入杂费新数据 ==========
        List<Long> feeId = amvo.getFeeValueIds();
        if (CollectionUtils.isEmpty(feeId)) {
            //不为空 → 说明用户选了标签 需要插入数据
            ArrayList<ApartmentFeeValue> arrFee = new ArrayList<>();
            for (Long s : feeId) {
                ApartmentFeeValue apartmentFee = ApartmentFeeValue.builder()
                        .apartmentId(apartmentId)
                        .feeValueId(s)
                        .build();
                arrFee.add(apartmentFee);
            }
            apartmentFeeValueService.saveBatch(arrFee);
        }

        // ========== 插入图片新数据 ==========
        List<com.atguigu.lease.web.admin.vo.graph.GraphVo> arrGraph = amvo.getGraphVoList();
        if (CollectionUtils.isEmpty(arrGraph)) {
            ArrayList<GraphVo> arrGraphs = new ArrayList<GraphVo>();
            for (com.atguigu.lease.web.admin.vo.graph.GraphVo s : arrGraph) {
                GraphVo graphInfo = new GraphVo();
                //图片ID
                graphInfo.setItemId(apartmentId);
                //图片类型: 1公寓 2房间
                graphInfo.setItemType(ItemType.APARTMENT);
                graphInfo.setName(s.getName());
                graphInfo.setUrl(s.getUrl());
                arrGraphs.add(graphInfo);
            }
            graphInfoService.saveBatch(arrGraphs);

        }
    }

    @Override
    public void pageQuery(IPage<ApartmentItemVo> page, @Param("queryVo") ApartmentQueryVo queryVo) {
        //业务层里需要调用mapper层 , 实现SQL逻辑,但是mapper层的参数第一个必须要是IPage
        apartmentInfoMapper.pageQuerys(page, queryVo);
    }

    @Override
    public ApartmentDetailVo QueryApartmentById(Long id) {
        // 1. 查询id对应公寓详情,这里返回 apartmentInfo 对象
        ApartmentInfo apartmentInfo = getById(id);
        // 2. 查询id对应配套集合
        List<FacilityInfo> facilityInfoList = facilityInfoMapper.QueryApartmentFacility(id);
        // 3. 查询id对应标签集合
        List<LabelInfo> labelInfoList = labelInfoMapper.QueryApartmentLabel(id);
        // 4. 查询id对应图片集合
        List<com.atguigu.lease.web.admin.vo.graph.GraphVo> graphInfoList = graphInfoMapper.QueryByApartmentGraph(id, ItemType.APARTMENT);
        // 5. 查询id对应的杂费集合
        List<FeeValueVo> feeValueInfoList = feeValueMapper.QueryByApartmentFee(id);
        // 6. 结果合并
        ApartmentDetailVo vo = new ApartmentDetailVo();
        //要把刚刚查询的数据赋给vo
        vo.setFacilityInfoList(facilityInfoList);
        vo.setLabelInfoList(labelInfoList);
        vo.setGraphVoList(graphInfoList);
        vo.setFeeValueVoList(feeValueInfoList);
        // 把A赋值给B, 把基本信息复制给Vo ,目前Vo有四个集合+一个基本信息,装载着全部数据
        BeanUtils.copyProperties(apartmentInfo, vo);
        return vo;
    }

    @Override
    public void customRemoveById(Long id) {
        //判断房间是否存在
        LambdaQueryWrapper<RoomInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoomInfo::getApartmentId, id);
        long count = roomInfoService.count();
        if (count > 0) {
            throw new LeaseException(ResultCodeEnum.DELETE_ERROR, "请删除子集");
        }

        //删除公寓基本信息
        this.removeById(id);
        //删除配套_图片
        LambdaQueryWrapper<GraphVo> wrapperGraph = new LambdaQueryWrapper<>();
        wrapperGraph.eq(GraphVo::getItemId, ItemType.APARTMENT);
        wrapperGraph.eq(GraphVo::getItemId, id);
        boolean b = graphInfoService.removeById(wrapperGraph);
        if (b) {
            System.out.println("图片信息删除成功");
        }
        //删除配套_配套
        LambdaQueryWrapper<ApartmentFacility> wrapperFacitity = new LambdaQueryWrapper<>();
        wrapperFacitity.eq(ApartmentFacility::getApartmentId, id);
        boolean b1 = apartmentFacilityService.removeById(wrapperGraph);
        if (b1) {
            System.out.println("配套信息删除成功");
        }
        //删除配套_标签
        LambdaQueryWrapper<ApartmentLabel> wrapperLabel = new LambdaQueryWrapper<>();
        wrapperLabel.eq(ApartmentLabel::getApartmentId, id);
        boolean b2 = apartmentLabelService.removeById(wrapperLabel);
        if (b2) {
            System.out.println("标签信息删除成功");
        }
        //删除配套_杂费
        LambdaQueryWrapper<ApartmentFeeValue> wrapperFee = new LambdaQueryWrapper<>();
        wrapperFee.eq(ApartmentFeeValue::getApartmentId, id);
        boolean b3 = apartmentFeeValueService.removeById(wrapperFee);
        if (b3) {
            System.out.println("杂费信息删除成功");
        }
    }


}




